/**
 * Copyright (C) 2010 Hamburg Sud
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hamburgsud.log4testing.core.junit;

import com.hamburgsud.log4testing.core.data.TestStatus;
import com.hamburgsud.log4testing.core.data.TestStep;
import com.hamburgsud.log4testing.core.data.TestStepContainer;

//TODO create a new module especially for junit and move this file into to. Get also the JUnit test case of aludratest and put it the same project.
public class Assert {

	/**
	 * Method that throws a Assertion with the message from Parameter TestStep
	 * 
	 * @param testStep
	 *            TestStep which is needed for the message
	 */
	static private void throwAssertion(final TestStep testStep) {
		final String message = testStep.getMessage();
		throw new AssertionError(message == null ? "" : message);
	}

	/**
	 * Encapsulates the checking if the parameter TestStep Status is equal to
	 * the amount of parameters TestStatus
	 * 
	 * @param testStep
	 *            the testStep which Status should be checked
	 * @param testStatus
	 *            the amount of TestStatus against which the testStep should be
	 *            checked
	 * @return if the testStep Status equals the given status
	 */
	static private boolean isOne(final TestStep testStep,
			final TestStatus... testStatus) {
		boolean isOne = false;
		for (TestStatus status : testStatus) {
			if (testStep.getStatus() == status) {
				isOne = true;
			}
		}
		return isOne;
	}

	/**
	 * Checks if parameter TestStep Status is equal to the parameters TestStatus
	 * and uses therefore the function isOne.
	 * 
	 * @param testStep
	 *            the testStep which Status should be checked
	 * @param testStatus
	 *            the amount of TestStatus which should be checked
	 */
	static public void assertThatOne(final TestStep testStep,
			final TestStatus... testStatus) {
		if (!isOne(testStep, testStatus)) {
			throwAssertion(testStep);
		}
	}

	/**
	 * Checks if parameter TestStep Status is not equal to the parameters
	 * TestStatus and uses therefore the function isOne.
	 * 
	 * @param testStep
	 *            the testStep which Status should be checked
	 * @param testStatus
	 *            the amount of TestStatus which should be checked
	 */
	static public void assertThatNone(final TestStep testStep,
			final TestStatus... testStatus) {
		if (isOne(testStep, testStatus)) {
			throwAssertion(testStep);
		}
	}

	/**
	 * Checks if the Status of the given testStep is OK
	 * 
	 * @param testStep
	 *            testStep which should be checked
	 */
	static public void assertOk(final TestStep testStep) {
		if (testStep.getStatus() != TestStatus.OK) {
			throwAssertion(testStep);
		}
	}

	/**
	 * Checks if in a testStepContainer all TestStep Status are OK
	 * 
	 * @param testStepContainer
	 *            testStepContainer which should be checked
	 */
	static public void assertOk(final TestStepContainer testStepContainer) {
		if (testStepContainer.getNumberOfFailed() != 0)
			throwAssertion(testStepContainer.getFirstFailed());
	}

	/**
	 * Checks if a TestStep is failed when its failed the Assertion will be
	 * thrown
	 * 
	 * @param testStep
	 *            testStep which should be checked
	 */
	static public void assertNotFailed(final TestStep testStep) {
		if (testStep.isFailed()) {
			throwAssertion(testStep);
		}
	}

	/**
	 * Checks if a TestStep in a TestStepContainer is failed
	 * 
	 * @param testStepContainer
	 *            testStepContainer which should be checked
	 */
	static public void assertNotFailed(final TestStepContainer testStepContainer) {
		if (testStepContainer.isFailed()) {
			throwAssertion(testStepContainer.getFirstFailed());
		}
	}

}
